package com.xbongbong.paas.help.menu;

import com.xbongbong.admin.pojo.dto.MirrorRollBackDTO;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.enums.EnableEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.dto.FormEntityAddDTO;
import com.xbongbong.paas.pojo.dto.FormExplainAddDTO;
import com.xbongbong.paas.pojo.dto.MenuFormAddDTO;
import com.xbongbong.paas.pojo.dto.MenuGroupAddDTO;
import com.xbongbong.paas.pojo.dto.ProcessOpenDistributorDTO;
import com.xbongbong.paas.pojo.vo.MenuGroupAddVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.service.PaasMenuService;
import com.xbongbong.paas.service.PaasProcessTemplateService;
import com.xbongbong.paas.service.init.AbstractInitMenuHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.enums.AccessLinkEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.AppStoreErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CreditManagement;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.menu.enums.DistributorMenuEnum;
import com.xbongbong.pro.enums.menu.enums.FundManagementMenuEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.form.pojo.dto.FormAddBatchDTO;
import com.xbongbong.pro.form.pojo.vo.FormAddBatchVO;
import com.xbongbong.pro.formexplain.pojo.dto.FormExplainAddBatchDTO;
import com.xbongbong.pro.formexplain.pojo.vo.FormExplainAddBatchVO;
import com.xbongbong.pro.menu.pojo.dto.MenuFormAddBatchDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuInitDTO;
import com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO;
import com.xbongbong.pro.menu.pojo.vo.MenuInitVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CouponTempleteEntity;
import com.xbongbong.saas.domain.entity.PromotionActivityEntity;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.MarketingBaseEnum;
import com.xbongbong.saas.enums.dictionary.MarketingStatusEnum;
import com.xbongbong.saas.model.CouponTempleteModel;
import com.xbongbong.saas.model.PromotionActivityModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 *
 * @author lee
 * @version v1.0
 * @date 2020/12/21 13:46
 * @since v1.0 经销商应用生成和菜单初始化
 */
@Component
public class InitDistributorMenuHelp extends AbstractInitMenuHelp {

    private static final Logger LOG = LoggerFactory.getLogger(InitCrmMenuHelp.class);

    @Resource
    private PaasMenuService paasMenuService;
    @Resource
    private PaasFormService paasFormService;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private InitMenuHelp initMenuHelp;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private PromotionActivityModel promotionActivityModel;
    @Resource
    private CouponTempleteModel couponTempleteModel;
    @Resource
    private InitDistributorMenuHelp initDistributorMenuHelp;
    @Resource
    private InitMarketingManagementHelp initMarketingManagementHelp;
    @Resource
    private InitOrderCenterMenuHelp initOrderCenterMenuHelp;
    @Resource
    private PaasProcessTemplateService paasProcessTemplateService;
    @Resource
    private InitFundManagementMenuHelp initFundManagementMenuHelp;
    @Resource
    private FundSetService fundSetService;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private InitPriceMenuHelp initPriceMenuHelp;

    @Override
    public List<String> alias() {
        return Arrays.asList(SystemAppMenuEnum.DISTRIBUTOR.getAlias());
    }

    @Override
    public MenuInitVO initApp(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        // 初始化经销商需要有进销存
        PaasAppEntity paasAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.JXC.getAlias(), menuInitDTO.getCorpid());
        if (Objects.isNull(paasAppEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "请先开通进销存");
        }
        // 经销商已有时走开启逻辑
                    /*PaasAppEntity distributorAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.DISTRIBUTOR.getAlias(), menuInitDTO.getCorpid());
                    if (Objects.nonNull(distributorAppEntity)) {
                        initDistributorMenuHelp.enableDistributor(1, menuInitDTO.getCorpid());
                        break;
                    }*/
        menuInitDTO.setDistributorMark(DistributorMarkEnum.DISTRIBUTOR.getCode());
        // 经销商应用初始化
        MenuInitVO initDistributorMenuVO = initDistributorMenuHelp.initMenu(menuInitDTO, appMap);
        // 营销初始化
        menuInitDTO.setAlias(XbbRefTypeEnum.MARKETING_MANAGEMENT.getAlias());
        initMarketingManagementHelp.initMenu(menuInitDTO, appMap);
        // 订单中心初始化
        menuInitDTO.setAlias(XbbRefTypeEnum.ORDER_CENTER.getAlias());
        PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(),menuInitDTO.getCorpid());
        if (Objects.isNull(paasFormEntity)) {
            paasFormEntity = paasFormModel.getByBusinessTypeNoEnable(XbbRefTypeEnum.PRODUCT.getCode(),menuInitDTO.getCorpid());
        }
        menuInitDTO.setProductForm(paasFormEntity);
        MenuInitVO orderCenterMenuVO = initOrderCenterMenuHelp.initMenu(menuInitDTO, appMap);
        // 初始化出库单
        MenuInitVO orderCenterOutStockMenuVO = initOrderCenterMenuHelp.initOrderOutStock(menuInitDTO);
        // 初始化资金
        menuInitDTO.setAlias(XbbRefTypeEnum.ONLINE_PAYMENT_FLOW.getAlias());
        MenuInitVO fundMenuInitVO = initFund(EnableEnum.OPEN, menuInitDTO);
        // 初始化信用管理
        initCreditMenu(menuInitDTO);
        // 初始化支付默认账户
        initFundAccount(menuInitDTO, true);
        // 初始化配置项，电子面单，物流跟踪，价格管理
        initCompanyConfig4Distributor(menuInitDTO);
        // 产品应用下价目表初始化
        menuInitDTO.setAlias(XbbRefTypeEnum.DISTRIBUTOR.getAlias());
        //插入默认打印模板
        initDefaultPrintTemplates(menuInitDTO.getCorpid(),orderCenterMenuVO.getFormList(),XbbRefTypeEnum.CRM.getAlias(), DistributorMarkEnum.DISTRIBUTOR.getCode());
        initDefaultPrintTemplates(menuInitDTO.getCorpid(),orderCenterOutStockMenuVO.getFormList(),XbbRefTypeEnum.JXC.getAlias(), DistributorMarkEnum.DISTRIBUTOR.getCode());
        initDefaultPrintTemplates(menuInitDTO.getCorpid(),fundMenuInitVO.getFormList(),XbbRefTypeEnum.FUND_MANAGEMENT.getAlias(), DistributorMarkEnum.DISTRIBUTOR.getCode());
        initPriceMenuHelp.initMenu(menuInitDTO, appMap);
        return initDistributorMenuVO;
    }


    private void initCompanyConfig4Distributor(MenuInitDTO menuInitDTO) {
        String corpid = menuInitDTO.getCorpid();
        List<CompanyConfigEnum> enums = Arrays.asList(CompanyConfigEnum.ELECTRONIC_FACE_SHEET, CompanyConfigEnum.LOGISTICS_TRACKING, CompanyConfigEnum.PRICE_MANAGE);
        List<String> configAliasList = Arrays.asList(CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias(), CompanyConfigEnum.LOGISTICS_TRACKING.getAlias(), CompanyConfigEnum.PRICE_MANAGE.getAlias());
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", BasicConstant.ZERO);
        param.put("configAliasIn", configAliasList);
        param.put("noLimit", 1);
        List<CompanyConfigEntity> configEntities = companyConfigModel.findEntitys(param);
        List<CompanyConfigEntity> insertConfigList = new ArrayList<>();
        Outer:
        for (CompanyConfigEnum item : enums) {
            for (CompanyConfigEntity configEntity : configEntities) {
                if (item.getAlias().equals(configEntity.getConfigAlias())) {
                    configEntity.setConfigValue(BasicConstant.ONE.toString());
                    continue Outer;
                }
            }
            CompanyConfigEntity companyConfigEntity = new CompanyConfigEntity(corpid, item.getName(), item.getAlias(), BasicConstant.IS_USE.toString());
            insertConfigList.add(companyConfigEntity);
        }
        if (!insertConfigList.isEmpty()) {
            companyConfigModel.insertBatch(insertConfigList);
        }
        if (!configEntities.isEmpty()) {
            companyConfigModel.updateBatch(configEntities, corpid);
        }
    }

    /**
     * 开启/关闭经销商时，初始化/关闭(隐藏)/开启(显示)对应的菜单、form、explain
     *
     * （1）菜单：在线支付流水菜单
     * （2）form：初始化/关闭(隐藏)/开启(显示)，没有的时候初始化，初始化后只能更新-即关闭或开启。包含业务有：在线支付流水、回款计划、销项发票、应收款、回款单、预收款余额
     * （3）explain：只存在初始化，不用更新（通过form控制显隐）
     * @param enableEnum 开启or关闭
     * @param menuInitDTO 菜单初始化dto
     * @return com.xbongbong.pro.menu.pojo.vo.MenuInitVO
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public MenuInitVO initFund(EnableEnum enableEnum, MenuInitDTO menuInitDTO) throws XbbException {
        MenuInitVO menuInitVO = new MenuInitVO();
        try {
            String corpid = menuInitDTO.getCorpid();
            //资金相关菜单都在资金管理app下
            PaasAppEntity fundManagementApp = paasAppModel.getByAlias(XbbRefTypeEnum.FUND_MANAGEMENT.getAlias(), corpid);
            if (Objects.isNull(fundManagementApp)) {
                throw new XbbException(AppStoreErrorCodeEnum.API_ERROR_300001, AppStoreErrorCodeEnum.API_ERROR_300001.getMsg());
            }
            Long appId = fundManagementApp.getId();
            DistributorMarkEnum distributorMarkEnum = DistributorMarkEnum.DISTRIBUTOR;
            Integer distributorMark = distributorMarkEnum.getCode();
            /**
             第一步初始化在线支付流水菜单（如果存在，则只更新其enable状态）
             */
            XbbRefTypeEnum refOnlinePaymentFlow = XbbRefTypeEnum.ONLINE_PAYMENT_FLOW;
            PaasMenuEntity onlinePaymentFlowMenuEntity = paasMenuModel.getByAlias4Distributor(refOnlinePaymentFlow.getAlias(), corpid, distributorMark);
            FundManagementMenuEnum menuEnum = FundManagementMenuEnum.ONLINE_PAYMENT_FLOW;
            if (Objects.isNull(onlinePaymentFlowMenuEntity)) {
                onlinePaymentFlowMenuEntity = new PaasMenuEntity(corpid, appId, menuEnum.getName(), menuEnum.getAlias(),-1, menuEnum.getAccessLinkEnum().getUrl(), menuEnum.getAccessLinkEnum().getMobileUrl(), BasicConstant.ONE, menuEnum.getAccessLinkEnum().getColor(), menuEnum.getAccessLinkEnum().getIcon(), menuInitDTO.getUserId());
                //初始化的在线流水菜单标识为经销商的
                onlinePaymentFlowMenuEntity.setDistributorMark(distributorMark);
            }
            onlinePaymentFlowMenuEntity.setEnable(enableEnum.getCode());
            paasMenuModel.save(onlinePaymentFlowMenuEntity);
            /**
             第二步初始化经销商form：在线支付流水、回款计划、销项发票、应收款、回款单、预收款余额（如果存在，则只更新其【hidden】状态）
             在线流水当前只有经销商模板使用，因此只初始化经销商类型的模板
             */
            List<PaasFormEntity> formUpdateList = new ArrayList<>();
            Long now = DateTimeUtil.getInt();
            //开启经销商，则hidden为0不隐藏；关闭经销商则hidden为1隐藏
            Integer hidden = Objects.equals(enableEnum.getCode(), EnableEnum.OPEN.getCode()) ? BasicConstant.ZERO : BasicConstant.ONE;
            //需要初始化经销商模板的业务
            List<String> aliasIn = FundManagementMenuEnum.getHasDistributorFormBusinessAlias();
            List<Integer> businessTypeList = FundManagementMenuEnum.getHasDistributorFormBusinessTypes();
            //读取资金管理应用下要初始化经销商form对应的菜单list
            Map<String, Object> menuParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            menuParam.put("corpid", corpid);
            menuParam.put("appId", appId);
            menuParam.put("aliasIn", aliasIn);
            menuParam.put("del", BasicConstant.ZERO);
            menuParam.put("saasMark", SaasMarkEnum.SAAS.getCode());
            List<PaasMenuEntity> targetMenuList = paasMenuModel.findEntitys(menuParam);
            //得到要初始化经销商form的formList（如果初始化过则只更新其hidden）
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("businessTypeList", businessTypeList);
            param.put("distributorMark", distributorMark);
            param.put("del", BasicConstant.ZERO);
            List<PaasFormEntity> targetFormList = paasFormModel.findEntity(param);
            //businessType-PaasFormEntity
            Map<Integer, PaasFormEntity> formMap = new HashMap<>(targetFormList.size());
            //存放已经有经销商form的菜单ids，此类无用再插入新的form和explain
            Set<Long> distributorMenuIds = new HashSet<>();
            for (PaasFormEntity paasFormEntity : targetFormList) {
                formMap.put(paasFormEntity.getBusinessType(), paasFormEntity);
                if (Objects.equals(paasFormEntity.getDistributorMark(), distributorMark)) {
                    distributorMenuIds.add(paasFormEntity.getMenuId());
                }
                if (!Objects.equals(paasFormEntity.getHidden(), hidden)) {
                    //确认是否要更新hidden（已经显示的无需再显示，已隐藏的无需再隐藏）
                    paasFormEntity.setHidden(hidden);
                    paasFormEntity.setUpdateTime(now);
                    formUpdateList.add(paasFormEntity);
                }
            }
            if (formUpdateList.size() > 0) {
                paasFormModel.updateBatch(formUpdateList, corpid);
            }
            //去除已经初始化过form的菜单
            Iterator<PaasMenuEntity> iterator = targetMenuList.iterator();
            while (iterator.hasNext()) {
                PaasMenuEntity next = iterator.next();
                if (distributorMenuIds.contains(next.getId())) {
                    iterator.remove();
                }
            }
            //剩余的都为要新增form和解释的，直接插入即可
            if (targetMenuList.size() > 0) {
                FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
                BeanUtil.copyProperties(menuInitDTO, formAddBatchDTO);
                List<FormEntityAddDTO> formList = new ArrayList<>();
                //初始化经销商资金相关form
                initFundManagementMenuHelp.getFormList(formList, targetMenuList, distributorMarkEnum);
                formAddBatchDTO.setFormList(formList);
                FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
                if (Objects.isNull(formAddBatchVO)) {
                    throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350010, TemplateErrorCodeEnum.API_ERROR_350010.getMsg());
                }
                List<PaasFormEntity> formInsertList = formAddBatchVO.getFormList();
                if (CollectionUtils.isEmpty(formInsertList)) {
                    return menuInitVO;
                }
                /**
                 第三步初始化经销商explain：在线支付流水、回款计划、销项发票、应收款、回款单、预收款余额
                 在线流水当前只有经销商模板使用，因此只初始化经销商类型的模板
                 */
                Long modelType = fundSetService.getModelType(corpid, XbbRefTypeEnum.CRM);
                ModelTypeEnum modelTypeEnum = ModelTypeEnum.getByCode(modelType);
                // 插入表单对应的字段解释
                initFundManagementMenuHelp.formExplainAddBatch(menuInitDTO, formAddBatchVO, distributorMarkEnum, modelTypeEnum);
                //formInsertList内的isProcessForm已处理
                if (!commonHelp.isOpenWorkFlow(corpid)) {
                    ProcessOpenDistributorDTO processOpenDistributorDTO = new ProcessOpenDistributorDTO();
                    //把登录信息copy进入dto
                    BeanUtil.copyProperties(menuInitDTO, processOpenDistributorDTO);
                    for (PaasFormEntity paasFormEntity : formInsertList) {
                        if (Objects.equals(paasFormEntity.getIsProcessForm(), BasicConstant.ONE)) {
                            //把该form的appId、menuIdcopy进入dto
                            BeanUtil.copyProperties(paasFormEntity, processOpenDistributorDTO);
                            processOpenDistributorDTO.setFormId(paasFormEntity.getId());
                            paasProcessTemplateService.createProcess4Distributor(processOpenDistributorDTO);
                        }
                    }
                }
                menuInitVO.setFormList(formInsertList);
            }
        } catch (Exception e){
            LOG.error("InitMenuHelp.initFund 初始化经销商资金菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitVO;
    }

    /**
     * 初始化信用管理相关菜单
     * @param menuInitDTO - 需要 corpid, userid, distributorMark
     * @return
     * @author xingxing.xiao
     */
    public void initCreditMenu(MenuInitDTO menuInitDTO) throws XbbException {
        String corpid = menuInitDTO.getCorpid();
        // 查询当前公司的资金应用信息
        PaasAppEntity fundApp = paasAppModel.getByAlias(XbbRefTypeEnum.FUND_MANAGEMENT.getAlias(), corpid);
        Long appId = fundApp.getId();

        // 判断菜单是否存在
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID, corpid);
        params.put(ParameterConstant.APPID, appId);
        params.put("aliasIn", Arrays.asList(XbbRefTypeEnum.CREDIT_MANAGEMENT.getAlias(), XbbRefTypeEnum.CREDIT_LIMIT.getAlias(), XbbRefTypeEnum.CREDIT_FIXED_LIMIT.getAlias(), XbbRefTypeEnum.CREDIT_TEMPORARY_LIMIT.getAlias(), XbbRefTypeEnum.CREDIT_CARD_BILL.getAlias()));
        params.put("distributorMark", menuInitDTO.getDistributorMark());
        Integer menuCount = paasMenuModel.getEntitysCount(params);
        if (menuCount > 0) {
            throw new XbbException(CreditManagement.API_ERROR_253002);
        }

        // 添加菜单分组
        MenuGroupAddDTO menuGroupAddDTO = new MenuGroupAddDTO();
        BeanUtil.copyProperties(menuInitDTO, menuGroupAddDTO);
        menuGroupAddDTO.setParentId(0L);
        setMenuGroupParam(appId, menuGroupAddDTO, FundManagementMenuEnum.CREDIT_MANAGEMENT);
        MenuGroupAddVO menuGroupAddVO = paasMenuService.addMenu(menuGroupAddDTO);

        // 添加分组下子菜单
        MenuFormAddBatchDTO menuAddBatchDTO = new MenuFormAddBatchDTO();
        BeanUtil.copyProperties(menuGroupAddDTO, menuAddBatchDTO);
        List<MenuFormAddDTO> crmFormMenuList = new ArrayList<>();
        for (FundManagementMenuEnum menuEnum : FundManagementMenuEnum.values()) {
            if (Objects.equals(menuEnum.getParent(), FundManagementMenuEnum.CREDIT_MANAGEMENT.getAlias())) {
                MenuFormAddDTO menuFormAddDTO = new MenuFormAddDTO();
                BeanUtil.copyProperties(menuInitDTO, menuFormAddDTO);
                menuFormAddDTO.setParentId(menuGroupAddVO.getMenuId());
                setMenuFormParam(appId, menuFormAddDTO, menuEnum);
                crmFormMenuList.add(menuFormAddDTO);
            }
        }
        menuAddBatchDTO.setMenuList(crmFormMenuList);
        MenuFormAddBatchVO menuFormAddBatchVO = paasMenuService.addBatchFormMenu(menuAddBatchDTO);

        // 经销商标识
        DistributorMarkEnum distributorMarkEnum = DistributorMarkEnum.getByCode(menuInitDTO.getDistributorMark());

        // 插入菜单对应的表单
        FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
        BeanUtil.copyProperties(menuInitDTO, formAddBatchDTO);
        List<FormEntityAddDTO> formList = new ArrayList<>();
        // 通过分组菜单，得到需要插入的表单列表
        initFundManagementMenuHelp.getFormList(formList, menuFormAddBatchVO.getMenuList(), distributorMarkEnum);
        formAddBatchDTO.setFormList(formList);
        FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
        if (Objects.isNull(formAddBatchVO)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        // 插入表单对应的字段解释
        initFundManagementMenuHelp.formExplainAddBatch(menuInitDTO, formAddBatchVO, distributorMarkEnum, ModelTypeEnum.PLAN);
        // 临时额度、固定额度加上默认审批流
        ProcessOpenDistributorDTO processOpenDistributorDTO = new ProcessOpenDistributorDTO();
        BeanUtil.copyProperties(menuInitDTO, processOpenDistributorDTO);
        List<PaasFormEntity> paasFormList = formAddBatchVO.getFormList();
        for (PaasFormEntity paasFormEntity : paasFormList) {
            if (Objects.equals(paasFormEntity.getIsProcessForm(), BasicConstant.ONE)) {
                BeanUtil.copyProperties(paasFormEntity, processOpenDistributorDTO);
                processOpenDistributorDTO.setFormId(paasFormEntity.getId());
                paasProcessTemplateService.createProcess4Distributor(processOpenDistributorDTO);
            }
        }
    }


    private void setMenuGroupParam(Long appId, MenuGroupAddDTO menuGroupAddDTO, FundManagementMenuEnum menuEnum) {
        menuGroupAddDTO.setAppId(appId);
        menuGroupAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        menuGroupAddDTO.setAlias(menuEnum.getAlias());
        menuGroupAddDTO.setName(menuEnum.getName());
        AccessLinkEnum accessLinkEnum = menuEnum.getAccessLinkEnum();
        menuGroupAddDTO.setIcon(accessLinkEnum.getIcon());
        menuGroupAddDTO.setColor(accessLinkEnum.getColor());
        menuGroupAddDTO.setUrl(accessLinkEnum.getUrl());
        menuGroupAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
        menuGroupAddDTO.setType(menuEnum.getType());
    }

    private void setMenuFormParam(Long appId, MenuFormAddDTO menuFormAddDTO, FundManagementMenuEnum menuEnum) {
        menuFormAddDTO.setAppId(appId);
        menuFormAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        menuFormAddDTO.setAlias(menuEnum.getAlias());
        menuFormAddDTO.setName(menuEnum.getName());
        AccessLinkEnum accessLinkEnum = menuEnum.getAccessLinkEnum();
        menuFormAddDTO.setIcon(accessLinkEnum.getIcon());
        menuFormAddDTO.setColor(accessLinkEnum.getColor());
        menuFormAddDTO.setUrl(accessLinkEnum.getUrl());
        menuFormAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
        menuFormAddDTO.setType(menuEnum.getType());
    }

    /**
     * crm菜单初始化
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param menuInitDTO
     * @return void
     * @throws XbbException
     */
    @Override
    public MenuInitVO initMenu(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        MenuInitVO menuInitVO = new MenuInitVO();
        try {
            // 获取下应用id
            Long appId = appMap.get(SystemAppMenuEnum.DISTRIBUTOR.getAlias()).getId();
            menuInitDTO.setAppId(appId);
            // 插入除分组外对应的菜单
            MenuFormAddBatchVO menuFormAddBatchVO = formAddBatch(menuInitDTO);
            if (Objects.isNull(menuFormAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            List<PaasMenuEntity> menuFormList = menuFormAddBatchVO.getMenuList();
            // 插入菜单对应的表单
            FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formAddBatchDTO);
            List<FormEntityAddDTO> formList = new ArrayList<>();
            // 通过分组菜单，得到需要插入的表单列表
            getFormList(formList, menuFormList);
            formAddBatchDTO.setFormList(formList);
            FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
            if (Objects.isNull(formAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 插入表单对应的字段解释
            formExplainAddBatch(menuInitDTO, formAddBatchVO);
            menuInitVO.setFormList(formAddBatchVO.getFormList());
        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("InitCrmMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitVO;
    }

    /**
     * 回退 CRM 表单到初始化
     * @param mirrorRollBackDTO
     * @param systemFormList 安装的系统表单
     * @param paasProductFormEntity
     * @throws XbbException
     * @author guohui.zhang
     */
    @Override
    public void rollBackInit(MirrorRollBackDTO mirrorRollBackDTO, List<Long> systemFormList, PaasFormEntity paasProductFormEntity) throws XbbException {

    }

    /**
     * 添加表单字段解释
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param menuInitDTO
     * @param formAddBatchVO 表单数据
     * @return 返回表单字段对象
     * @throws XbbException
     */
    public FormExplainAddBatchVO formExplainAddBatch(MenuInitDTO menuInitDTO, FormAddBatchVO formAddBatchVO) throws XbbException {
        FormExplainAddBatchVO formExplainAddBatchVO;
        try {
            List<PaasFormEntity> formResultList = formAddBatchVO.getFormList();
            FormExplainAddBatchDTO formExplainAddBatchDTO = new FormExplainAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formExplainAddBatchDTO);
            List<FormExplainAddDTO> formExplainList = new ArrayList<>();
            for (PaasFormEntity item : formResultList) {
                FormExplainAddDTO formExplainAddDTO = new FormExplainAddDTO();
                BeanUtil.copyProperties(item, formExplainAddDTO);
                formExplainAddDTO.setFormId(item.getId());
                String alias = XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias();
                // 初始化方法获取字段列表
                List<FieldAttrEntity> explainList = new ArrayList<>();
                if (!InitExplainsHelper.EMPTY_EXPLAIN.contains(item.getBusinessType())) {
                    explainList = InitExplainsHelper.initFieldAttrEntity(alias,menuInitDTO.getProductForm(), null, 1);
                }
                formExplainAddDTO.setFormList(explainList);
                formExplainList.add(formExplainAddDTO);
            }
            formExplainAddBatchDTO.setFormExplainList(formExplainList);
            formExplainAddBatchVO = paasFormExplainService.addBatch(formExplainAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formExplainAddBatch批量添加表单解释信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainAddBatchVO;
    }


    /**
     * 批量添加表单
     * @author lee
     * @date 2020/12/21 14:43
     * @param menuInitDTO
     * @return com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO
     * @throws XbbException
     */
    private MenuFormAddBatchVO formAddBatch(MenuInitDTO menuInitDTO) throws XbbException {
        MenuFormAddBatchVO menuFormAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            MenuFormAddBatchDTO distributorFormAddBatchDTO = new MenuFormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, distributorFormAddBatchDTO);
            distributorFormAddBatchDTO.setAppId(appId);
            List<MenuFormAddDTO> distributorFormMenuList = new ArrayList<>();
            for(DistributorMenuEnum distributorMenuEnum: DistributorMenuEnum.values()){
                MenuFormAddDTO menuFormAddDTO = new MenuFormAddDTO();
                BeanUtil.copyProperties(menuInitDTO, menuFormAddDTO);
                menuFormAddDTO.setAppId(appId);
                menuFormAddDTO.setParentId(0L);
                menuFormAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                menuFormAddDTO.setAlias(distributorMenuEnum.getAlias());
                menuFormAddDTO.setName(distributorMenuEnum.getName());
                AccessLinkEnum accessLinkEnum = distributorMenuEnum.getAccessLinkEnum();
                menuFormAddDTO.setIcon(accessLinkEnum.getIcon());
                menuFormAddDTO.setColor(accessLinkEnum.getColor());
                menuFormAddDTO.setUrl(accessLinkEnum.getUrl());
                menuFormAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                menuFormAddDTO.setType(distributorMenuEnum.getType());
                menuFormAddDTO.setDistributorMark(1);
                distributorFormMenuList.add(menuFormAddDTO);
            }
            distributorFormAddBatchDTO.setMenuList(distributorFormMenuList);
            menuFormAddBatchVO = paasMenuService.addBatchFormMenu(distributorFormAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formAddBatch批量添加表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuFormAddBatchVO;
    }

    /**
     * 根据菜单获取表单列表
     * @author lee
     * @date 2019/1/24 18:43
     * @param formList 表单列表
     * @param menuList 菜单列表
     * @return 返回需要插入的表单列表
     * @throws XbbException 业务异常
     */
    public List<FormEntityAddDTO> getFormList(List<FormEntityAddDTO> formList, List<PaasMenuEntity> menuList) throws XbbException{
        try {
            for (PaasMenuEntity item : menuList) {
                FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
                BeanUtil.copyProperties(item, formEntityAddDTO);
                DistributorMenuEnum distributorMenuEnum = DistributorMenuEnum.getByAlias(item.getAlias());
                if (Objects.isNull(distributorMenuEnum)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.BUSINESS_TYPE_NOT_EXIST);
                }
                Integer transferBusinessType = XbbRefTypeEnum.transferBusinessType4Distributor(distributorMenuEnum.getCode(), DistributorMarkEnum.DISTRIBUTOR.getCode());
                formEntityAddDTO.setBusinessType(distributorMenuEnum.getCode());
                formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                formEntityAddDTO.setLabels(getAppDefaultLabel(transferBusinessType));
                formEntityAddDTO.setCustomTitle(getAppDefaultTitle(transferBusinessType));
                formEntityAddDTO.setSummaryEntity(getAppDefaultSummary(transferBusinessType));
                formEntityAddDTO.setBusinessRules("0");
                formEntityAddDTO.setMenuId(item.getId());
                formList.add(formEntityAddDTO);
            }
        }catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.getFormList 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formList;
    }

    /**
     * 开启/关闭 经销商应用  这里的时已初始化完成的经销商模块开启关闭
     * @param enable
     * @param corpid
     * @param needCloseRelation 是否需要关闭价格管理，物流跟踪，电子面单
     */
    public void enableDistributor(Integer enable, String corpid, boolean needCloseRelation) throws XbbException {
        // 开启经销商应用，营销应用，订单中心应用，
        // 价格管理配置，物流跟踪配置，电子面单配置，
        // 价格管理，在线支付流水，信用管理，临时额度，固定额度菜单
        // 多模板菜单隐藏 出库发货单 回款计划 回款单 销项发票 应收款,生成对账单，经销商对账单列表，预收款余额，在线支付流水
        if (Objects.equals(enable, 1)) {
            // 经销商开启时校验是否有进销存
            PaasAppEntity paasAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.JXC.getAlias(), corpid);
            if (Objects.isNull(paasAppEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "请先开通进销存");
            }
        }
        List<String> appAliasList = Arrays.asList(XbbRefTypeEnum.DISTRIBUTOR.getAlias(), XbbRefTypeEnum.ORDER_CENTER.getAlias(), XbbRefTypeEnum.MARKETING_MANAGEMENT.getAlias());
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", BasicConstant.ZERO);
        param.put("aliasIn", appAliasList);
        List<PaasAppEntity> paasAppEntities = paasAppModel.findEntitys(param);
        if (!paasAppEntities.isEmpty()) {
            paasAppEntities.forEach(item -> item.setEnable(enable));
            paasAppModel.updateBatch(paasAppEntities, corpid);
        }
        if (Objects.equals(enable, 1) || needCloseRelation) {
            List<String> configAliasList = Arrays.asList(CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias(), CompanyConfigEnum.LOGISTICS_TRACKING.getAlias(), CompanyConfigEnum.PRICE_MANAGE.getAlias());
            param.put("configAliasIn", configAliasList);
            param.put("noLimit", 1);
            String enableStr = enable.toString();
            List<CompanyConfigEntity> configEntities = companyConfigModel.findEntitys(param);
            if (!configEntities.isEmpty()) {
                configEntities.forEach(item -> item.setConfigValue(enableStr));
                companyConfigModel.updateBatch(configEntities, corpid);
            }
        }
        List<String> aliasList = new ArrayList<>(Arrays.asList(XbbRefTypeEnum.ONLINE_PAYMENT_FLOW.getAlias(), XbbRefTypeEnum.CREDIT_MANAGEMENT.getAlias(), XbbRefTypeEnum.CREDIT_TEMPORARY_LIMIT.getAlias(), XbbRefTypeEnum.CREDIT_FIXED_LIMIT.getAlias()));
        if (Objects.equals(enable, 1) || needCloseRelation) {
            aliasList.add(XbbRefTypeEnum.PRICE_SET_PRODUCT.getAlias());
        }
        param.put("aliasIn", aliasList);
        param.put("distributorMark", DistributorMarkEnum.DISTRIBUTOR.getCode());
        List<PaasMenuEntity> paasMenuEntities = paasMenuModel.findEntitys(param);
        if (!paasMenuEntities.isEmpty()) {
            paasMenuEntities.forEach(item -> item.setEnable(enable));
            paasMenuModel.updateBatch(paasMenuEntities, corpid);
        }
        List<Integer> businessTypeList = new ArrayList<>();
        businessTypeList.add(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode());
        //再塞入有经销商form（及隐藏form）的资金businessType
        businessTypeList.addAll(FundManagementMenuEnum.getHasDistributorFormBusinessTypes());
        // 需要隐藏经销商form，否则生成对账单那边还会有问题
        businessTypeList.add(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        param.put("businessTypeList", businessTypeList);

        List<PaasFormEntity> paasFormEntities = paasFormModel.findEntity(param);
        Integer hidden = Objects.equals(enable, 1) ? 0 : 1;
        if (!paasFormEntities.isEmpty()) {
            paasFormEntities.forEach(item -> item.setHidden(hidden));
            paasFormModel.updateBatch(paasFormEntities, corpid);
        }
        paasRedisHelper.removeValue(RedisPrefixConstant.DISTRIBUTOR_XBB_ACCESS_TOKEN, corpid);
        if (Objects.equals(enable, 0)) {
            //下架活动
            try {
                offLineActivity(corpid);
            } catch (XbbException e) {
                e.printStackTrace();
            }
        }
    }

    public void offLineActivity(String corpid) throws XbbException {
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", BasicConstant.ZERO);
        param.put("status", MarketingStatusEnum.ONLINE.getCode());
        List<CouponTempleteEntity> couponTempleteEntities = couponTempleteModel.findEntities(param);

        for (CouponTempleteEntity entity : couponTempleteEntities) {
            String key = corpid + StringConstant.UNDER_LINE + entity.getId();
            String value = Objects.isNull(paasRedisHelper.getValue(RedisPrefixConstant.COUPON_NUM_KEY, key)) ? "0" : paasRedisHelper.getValue(RedisPrefixConstant.COUPON_NUM_KEY, key);
            entity.setGetNum(entity.getCouponNum() - Integer.parseInt(value));
            paasRedisHelper.removeValue(RedisPrefixConstant.COUPON_NUM_KEY, key);
            entity.setStatus(MarketingStatusEnum.OFFLINE.getCode());
            entity.getData().put(MarketingBaseEnum.STATUS.getAttr(),MarketingStatusEnum.OFFLINE.getCode());
        }
        couponTempleteModel.updateStatus(couponTempleteEntities, corpid);


        List<PromotionActivityEntity> promotionActivityEntities = promotionActivityModel.findEntities(param);
        for (PromotionActivityEntity promotionActivityEntity : promotionActivityEntities) {
            promotionActivityEntity.setStatus(MarketingStatusEnum.OFFLINE.getCode());
        }
        promotionActivityModel.updateStatus(promotionActivityEntities, corpid);
    }

    public void enableConfig(String value, List<String> configAliasList, String corpid) throws XbbException{

    }
}
